package com.momo.mal.util;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.momo.mal.Login;
import net.momo.mal.R;
import com.momo.mal.dashboard.Dashboard;
import com.momo.mal.database.MalDatabaseAdapter;
import com.momo.mal.entity.Anime;
import com.momo.mal.entity.History;
import com.momo.mal.entity.Manga;

public class Synchcronize extends AsyncTask<Void, Void, Integer> {

	private NotificationManager notificationManager;
	private MalDatabaseAdapter dbAdapter;
	private Context context;
	private NotificationCompat.Builder builder;
	private Notification notification;

	public Synchcronize(Context context) {
		dbAdapter = new MalDatabaseAdapter(context);

		notificationManager = (NotificationManager) context
				.getSystemService(Context.NOTIFICATION_SERVICE);
		builder = new NotificationCompat.Builder(context);

		Resources resources = context.getResources();
		builder.setContentTitle(resources.getString(R.string.app_name));
		builder.setContentText(resources.getString(R.string.text_sync));
		builder.setSmallIcon(R.drawable.ic_launcher);
		builder.setTicker(resources.getString(R.string.text_sync));
		builder.setWhen(System.currentTimeMillis());
		builder.setAutoCancel(false);
		builder.setDefaults(Notification.FLAG_NO_CLEAR);

		Intent intent = new Intent();
		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
		intent, Intent.FLAG_ACTIVITY_NEW_TASK);
		builder.setContentIntent(pendingIntent);

		notification = builder.build();
		notification.flags = Notification.FLAG_NO_CLEAR;

		this.context = context;
	}

	@Override
	protected Integer doInBackground(Void... params) {
		int error = 0;
		JSONObject jsonAnime = null, jsonManga = null;
		NodeList nodeListManga = null, nodeListAnime = null;

		try {

			Document documentManga = ConnectionUtil
					.getXML(ConnectionUtil.RSS_MANGA
							+ context.getSharedPreferences(Login.PREFS_NAME,
									context.MODE_PRIVATE).getString("username",
									""));
			if (documentManga != null) {
				nodeListManga = documentManga.getElementsByTagName("item");
			}

			Document documentAnime = ConnectionUtil
					.getXML(ConnectionUtil.RSS_ANIME
							+ context.getSharedPreferences(Login.PREFS_NAME,
									context.MODE_PRIVATE).getString("username",
									""));
			if (documentAnime != null) {
				nodeListAnime = documentAnime.getElementsByTagName("item");
			}

			jsonAnime = ConnectionUtil.get(
					ConnectionUtil.SECONDATY_API_HOST
							+ "animelist/"
							+ context.getSharedPreferences(Login.PREFS_NAME,
									context.MODE_PRIVATE).getString("username",
									""), context);

			jsonManga = ConnectionUtil.get(
					ConnectionUtil.SECONDATY_API_HOST
							+ "mangalist/"
							+ context.getSharedPreferences(Login.PREFS_NAME,
									context.MODE_PRIVATE).getString("username",
									""), context);

		} catch (JSONException e) {
			error = 1;
			notificationManager.cancel(0);
			e.printStackTrace();
		} catch (IOException e) {
			error = 1;
			notificationManager.cancel(0);
			e.printStackTrace();
		}

		try {
			if (error == 0) {
				saveManga(jsonManga);
				saveAnime(jsonAnime);

				dbAdapter.deleteHistory();
				if (nodeListManga != null) {
					saveHistory(nodeListManga, false);
				}
				if (nodeListAnime != null) {
					saveHistory(nodeListAnime, true);
				}
			}
		} catch (JSONException e) {
			error = 1;
			e.printStackTrace();
			notificationManager.cancel(0);
		} catch (IOException e) {
			error = 1;
			e.printStackTrace();
			e.printStackTrace();
		}

		return error;
	}

	@Override
	protected void onPreExecute() {
		notificationManager.notify(0, notification);
	}

	@Override
	protected void onPostExecute(Integer result) {
		try {
			if (result == 1) {
				Toast.makeText(
						context,
						context.getResources().getString(
								R.string.failed_load_data), Toast.LENGTH_LONG)
						.show();
				notificationManager.cancel(0);
			} else {
				Intent intent = new Intent();
				intent.setAction("com.momo.mal.action.synchronize");
				context.sendBroadcast(intent); 
				notificationManager.cancel(0);
			}
		} catch (Exception e) {
			Toast.makeText(
					context,
					context.getResources().getString(R.string.failed_load_data),
					Toast.LENGTH_LONG).show();
			notificationManager.cancel(0);
			e.printStackTrace();
		}
	}

	private void saveAnime(JSONObject jsonObject) throws JSONException {
		List<String> animeIds = dbAdapter.getAllAnime();
		JSONArray jsonArray = jsonObject.getJSONArray("anime");
		for (int a = 0; a < jsonArray.length(); a++) {
			JSONObject json = jsonArray.getJSONObject(a);
			Anime anime = new Anime();

			anime.setId(json.getString("id"));
			anime.setTitle(json.getString("title"));
			anime.setType(json.getString("type"));
			anime.setImageUrl(json.getString("image_url"));
			anime.setEpisode(json.getString("episodes"));
			anime.setStatus(json.getString("status"));
			anime.setWatchedEpisode(json.getString("watched_episodes"));
			anime.setWathcedStatus(AnimeUtil.parsingWatchedStatus(json
					.getString("watched_status")));
			anime.setScore(json.getString("score"));

			if (animeIds.contains(anime.getId())) {
				dbAdapter.updateAnime(anime);
			} else {
				anime.setPriority("0");
				dbAdapter.saveAnime(anime);
			}
		}

	}

	private void saveManga(JSONObject jsonObject) throws JSONException {
		List<String> mangaIds = dbAdapter.getAllManga();
		JSONArray jsonArray = jsonObject.getJSONArray("manga");
		for (int a = 0; a < jsonArray.length(); a++) {
			JSONObject json = jsonArray.getJSONObject(a);
			Manga manga = new Manga();

			manga.setId(json.getString("id"));
			manga.setTitle(json.getString("title"));
			manga.setType(json.getString("type"));
			manga.setChapterRead(json.getString("chapters_read"));
			manga.setChapters(json.getString("chapters").equalsIgnoreCase(
					"null") ? "0" : json.getString("chapters"));
			manga.setVolumes(json.getString("volumes").equalsIgnoreCase("null") ? "0"
					: json.getString("volumes"));
			manga.setVolumesRead(json.getString("volumes_read"));
			manga.setScore(json.getString("score"));
			manga.setStatus(json.getString("status"));
			manga.setReadStatus(MangaUtil.parsingReadStatus(json
					.getString("read_status")));
			manga.setImageUrl(json.getString("image_url"));

			if (mangaIds.contains(manga.getId())) {
				dbAdapter.updateManga(manga);
			} else {
				manga.setPriority("0");
				dbAdapter.saveManga(manga);
			}
		}
	}

	private void saveHistory(NodeList nodeList, boolean isAnime)
			throws JSONException, IOException {

		for (int a = 0; a < nodeList.getLength(); a++) {
			Node node = nodeList.item(a);
			Element element = (Element) node;
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				String link = element
						.getElementsByTagName("link")
						.item(0)
						.getTextContent()
						.substring(
								29,
								element.getElementsByTagName("link").item(0)
										.getTextContent().length());
				String id = link.substring(0, link.indexOf("/"));

				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				SimpleDateFormat format2 = new SimpleDateFormat(
						"EEE, d MMM yyyy HH:mm:ss Z");
				String updateDate = null;
				try {
					updateDate = format.format(format2.parse(element
							.getElementsByTagName("pubDate").item(0)
							.getTextContent()));
				} catch (DOMException e) {
					e.printStackTrace();
				} catch (ParseException e) {
					e.printStackTrace();
				}

				String title = element.getElementsByTagName("title").item(0)
						.getTextContent();
				
				History history = new History();
				history.setTitle(title.substring(0, title.length() - 3));
				history.setUpdateDate(updateDate);

				if (isAnime == true) {
					history.setMangaId("");
					history.setType("anime");
					history.setAnimeId(id);

					String description = element
							.getElementsByTagName("description").item(0)
							.getTextContent();
					history.setDescription(description.substring(0, description.length() - 3));

					if (dbAdapter.getAnimeById(id) == null) {
						String image = AnimeUtil.parsingAnimeFromJson(
								ConnectionUtil.get(
										ConnectionUtil.SECONDATY_API_HOST
												+ "anime/" + id, context))
								.getImageUrl();
						dbAdapter.insertHistory(history, image);
					} else {
						dbAdapter.insertHistory(history, dbAdapter
								.getAnimeById(id).getImageUrl());
					}
				} else {
					history.setMangaId(id);
					history.setType("manga");
					history.setAnimeId("");

					String description = (element.getElementsByTagName(
							"description").item(0).getTextContent()).replace(
							"Watching", "Reading").replace("Plan to Watch",
							"Plan to Read");
					history.setDescription(description.substring(0, description.length() - 3));

					if (dbAdapter.getMangaById(id) == null) {
						String image = MangaUtil.parsingMangaFromJson(
								ConnectionUtil.get(
										ConnectionUtil.SECONDATY_API_HOST
												+ "manga/" + id, context))
								.getImageUrl();
						dbAdapter.insertHistory(history, image);
					} else {
						dbAdapter.insertHistory(history, dbAdapter
								.getMangaById(id).getImageUrl());
					}
				}

			}
		}
	}
}

